위 코드의 경우 운영체제에서 정수 크기(4byte)의 메모리를 요청한다. 해당 메모리를 사용하여 객체를 만들고 메모리의 주소가 포함된 포인터를 반환한다.
int *ptr =new int;*ptr=7;
2-1. Initializing a dynamically allocated variable
동적 할당 과정에서 직접 초기화 | 유니온 초기화를 통해 변수를 초기화할 수 있다.
int *ptr1 = new int (1);int *ptr2 = new int {6};
3. Deleting single variable
동적 할당 변수의 경우 메모리 재사용을 위해 c++에 명시적으로 알려야한다. 이럴 경우 delete연산을 통해 수행된다.
delete ptr;ptr = nullptr;
4. 댕글링 포인터
댕글링 포인터란 이미 해제된 포인터를 계속 가리키고 있어 운영체제에게 반환된 메모리 영역을 읽고, 쓰고하는 문제가 생길 수 있는 상황을 말합니다.
댕글링 포인터 1. 이미 해제된 메모리를 계속 가리키고 있는 상황
#include <iostream>int main() { int *ptr = new int; *ptr = 7; delete ptr; std::cout<<*ptr; delete ptr; return 0;}
delete ptr을 통해 이미 해제된 메모리 영역의 주소를 가지고 있는 ptr 변수를 초기화하지 않을 경우 해당 주소를 계속 가지고 있는 것으로 읽기, 쓰기가 가능함. 이로 인하여 다른 프로그램이 해당 영역에 올라갔을때, 해당 메모리 값을 읽고, 쓰기가 가능해집니다.
위 코드를 시각적으로 나타내 봤습니다. new int를 통해서 4byte 만큼의 heap 영역의 공간을 만들고, 해당 영역의 주소를 ptr이라는 변수에 저장합니다. 그 다음 7이라는 값을 저장하고, delete ptr 순간 해당 영역은 운영체제에게 반환되므로, 영역의 값이 사라집니다. 하지만 ptr의 값은 여전히 해당 주소를 기억하고 있으므로, *ptr = 3을 해제 후에 하면 해당 주소 영역에 3이 저장되는 것을 볼 수 있습니다.
댕글링 포인터 2. 해제된 메모리 영역의 주로를 다른 포인터가 가리키고 있는 경우
#include <iostream>int main() { int *ptr = new int; int *otherPtr = ptr; delete ptr; ptr = nullptr; return 0;}
5. Operator new can fail
드문 경우 운영체제에 메모리를 요청할 때 운영체제에 메모리가 없을 수 있다. 이런 경우 기본적으로 new가 실패하면 bad_alloc 예외가 throw된다.
따라서 예외가 발생할 경우 null pointer를 반환하도록 만드는 것이 좋다.
int* value = new (std::nothrow) int;
혹시나 null을 역참조할 경우 정의되지 않은 동작이 발생하기 때문에 메모리 요청 성공했는지 확인한 후 메모리를 사용하는 것이 좋다.
int* value = new (std::nothrow) int;if(!value) { std::cout<<"Could not allocate memory";}
6. Memory Leak
동적 메모리 할당은 범위가 없다. 따라서 명시적으로 할당이 해제되거나 프로그램이 종료될 때까지 할당된 상태를 유지한다.
여기서 동적 할당한 메모리를 가리키는 포인터를 잃어버리면 더 이상 해제할 수 없다 이로 인하여 메모리 누수 현상이 생기는데, 프로그램이 운영체제로 되돌리기 전에 동적으로 할당된 메모리의 일부 비트 주소를 잃어버리면 발생한다. 또한 포인터에 다른 값을 할당하면 메모리 누수 현상이 생길 위험이 있다.
int value = 5;int* ptr = new int;ptr = &value;
int value = 5;int* ptr = new int;delete ptr;ptr = &value;
Note
이중 포인터 또한 메모리 누수가 발생한다.
int** ptr = new int*; // 포인터를 가리키는 포인터
*ptr = new int(5);
delete *ptr; // 안쪽 메모리 해제
delete ptr; // 바깥 포인터 해제
// 둘 중 하나라도 빠지면 메모리 누수 발생